package com.wnxy.sddfp.system.controller;

import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import com.netflix.hystrix.contrib.javanica.conf.HystrixPropertiesManager;
import com.wnxy.sddfp.client.bank.TestBankApi;
import com.wnxy.sddfp.common.exception.BusinessException;
import com.wnxy.sddfp.common.result.Result;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;

/**
 * 测试负载均衡：
 * 1、客户端项目远程调用；
 * 2、启动多个服务端
 * 3、客户端查看调用的是哪个服务端
 */
@RestController
@RequestMapping("/test")
public class TestController {

    // 注入feign客户端接口代理对象
    @Autowired
    private TestBankApi testBankApi;

    /**
     * 测试
     * 启动时候报错：
     * 1、Consider renaming one of the beans or enabling overriding by setting
     * spring.main.allow-bean-definition-overriding=true
     * 2、解决： 在yml中配置允许bean的重写
     */
    @GetMapping
    public String loadbalance(){
        return testBankApi.showPort();
    }


    /**
     * 测试服务降级、服务熔断
     * @HystrixCommand
     * 1、服务降级熔断注解
     * 2、通过fallbackMethod指定降级方法：当业务执行出现异常时候走降级业务逻辑
     * 3、注意：fallbackMethod指定的降级方法返回值、参数必须与业务方法一致
     */
    @GetMapping("/find/{id}")
    @HystrixCommand(fallbackMethod = "errorFallback",commandProperties = {
            // 是否开启断路器
            @HystrixProperty(name = HystrixPropertiesManager.CIRCUIT_BREAKER_ENABLED,value = "true"),
            // 请求错误率大于 50% 就启动熔断器
            @HystrixProperty(name = HystrixPropertiesManager.CIRCUIT_BREAKER_ERROR_THRESHOLD_PERCENTAGE,value = "50"),
            // 默认10秒内访问接口达到20次，且错误率大于50%则打开断路器，触发熔断； 为了方便测试，这里修改请求数为10
            @HystrixProperty(name = HystrixPropertiesManager.CIRCUIT_BREAKER_REQUEST_VOLUME_THRESHOLD,value = "10"),
            //断路多久以后开始尝试是否恢复，默认5s
            @HystrixProperty(name = HystrixPropertiesManager.CIRCUIT_BREAKER_SLEEP_WINDOW_IN_MILLISECONDS,value = "10000")
    })
    public Result find(@PathVariable("id")Integer id){
        if (id < 0) { // 模拟异常，进行服务降级
            throw new BusinessException();
        }
        return Result.ok();
    }
    // 服务降级方法; 这里的参数、返回值要与find()方法一致；
    // 否则报错：fallback method wasn't found: errorFallback...
    public Result errorFallback(@PathVariable("id")Integer id){
        return Result.fail("参数必须大于0，服务降级");
    }
}


















